[Py-Intro] Aula 05

Funções e arquivos

O que você vai aprender nesta aula?

  • Funções

    • Definir nções
    • Funções como objetos
    • Argumentos padrão
    • Invocar funções pelos nomes dos argumentos (keyword arguments)
    • Empacotamento e desempacotamento de argumentos
  • Arquivos

    • Como ler e escrever arquivos
    • Trabalhando com arquivos CSV (Comma-separated values)

Funções

Definindo funções

Nas aulas anteriores já usamos e definimos muitas funções. Nesta aula revisaremos como essas coisas acontecem e aprofundaremos o assunto.


In [1]:
def dobra(x):
    return x * 2

In [2]:
dobra(10)


Out[2]:
20

Vale notar que o Python não faz checagem de tipos, então podemos usar nossa função dobra() com outros tipos de argumentos:


In [9]:
dobra('do')


Out[9]:
'dodo'

In [10]:
dobra([1, 2, 3])


Out[10]:
[1, 2, 3, 1, 2, 3]

Uma função pode receber mais de um parâmetro:


In [16]:
def soma(a, b, c, d):
    return a + b + c + d

In [17]:
soma(1, 2, 3, 4)


Out[17]:
10

In [19]:
soma('h', 'o', 'j', 'e')


Out[19]:
'hoje'

A documentação de funções é feita utilizando docstring. Docstring são lorem ipsum dolor sit amet:


In [22]:
def fatorial(n):
    """ Retorna o fatorial de n (n!)"""
    return 1 if n < 1 else n * fatorial(n - 1)

In [25]:
fatorial(3), fatorial(4), fatorial(5)


Out[25]:
(6, 24, 120)

Funções como objetos

Funções em python podem ser tratadas como outros objetos (no jargão formal diz-se que funções são objetos de primeira classe)


In [26]:
fat = fatorial
fat(3), fat(4), fat(5)


Out[26]:
(6, 24, 120)

In [27]:
fat


Out[27]:
<function __main__.fatorial>

In [28]:
type(fat)


Out[28]:
function

É possível acessar atributos desse objeto function:


In [29]:
fat.__doc__


Out[29]:
' Retorna o fatorial de n (n!)'

Para conhecermos os atributos e métodos de um objeto function podemos usar a função dir() que retorna os métodos atributos de um objeto


In [30]:
dir(fat)


Out[30]:
['__annotations__',
 '__call__',
 '__class__',
 '__closure__',
 '__code__',
 '__defaults__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__get__',
 '__getattribute__',
 '__globals__',
 '__gt__',
 '__hash__',
 '__init__',
 '__kwdefaults__',
 '__le__',
 '__lt__',
 '__module__',
 '__name__',
 '__ne__',
 '__new__',
 '__qualname__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__']

Os métodos e atributos envoltos em __ são conhecidos como Métodos Mágicos ou Métodos Dunder (Double UNDERline) e serão vistos no minicurso de Orientação a Objetos


In [31]:
fat.__name__


Out[31]:
'fatorial'

In [32]:
fat.__doc__


Out[32]:
' Retorna o fatorial de n (n!)'

É possível acessar o metadados e o bytecode dessas funções:


In [33]:
fat.__code__


Out[33]:
<code object fatorial at 0x7f185c2acc90, file "<ipython-input-22-6cb648e23c5e>", line 1>

In [34]:
dir(fat.__code__)


Out[34]:
['__class__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__lt__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'co_argcount',
 'co_cellvars',
 'co_code',
 'co_consts',
 'co_filename',
 'co_firstlineno',
 'co_flags',
 'co_freevars',
 'co_kwonlyargcount',
 'co_lnotab',
 'co_name',
 'co_names',
 'co_nlocals',
 'co_stacksize',
 'co_varnames']

In [38]:
fat.__code__.co_name


Out[38]:
'fatorial'

In [40]:
fat.__code__.co_varnames


Out[40]:
('n',)

Bytecode:


In [41]:
fat.__code__.co_code


Out[41]:
b'|\x00\x00d\x01\x00k\x00\x00r\x10\x00d\x01\x00S|\x00\x00t\x00\x00|\x00\x00d\x01\x00\x18\x83\x01\x00\x14S'

In [42]:
import dis
dis.dis(fat)


  3           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (1)
              6 COMPARE_OP               0 (<)
              9 POP_JUMP_IF_FALSE       16
             12 LOAD_CONST               1 (1)
             15 RETURN_VALUE
        >>   16 LOAD_FAST                0 (n)
             19 LOAD_GLOBAL              0 (fatorial)
             22 LOAD_FAST                0 (n)
             25 LOAD_CONST               1 (1)
             28 BINARY_SUBTRACT
             29 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             32 BINARY_MULTIPLY
             33 RETURN_VALUE

Como mostramos anteriormente é possível enviar funções como argumentos de outras funções. No caso usamos esse artifício para mudar o funcionamento padrão da função de ordenação sorted():


In [53]:
bromas = {'z': 10, 'n': 5, 'm': 7}
bromas


Out[53]:
{'m': 7, 'n': 5, 'z': 10}

In [54]:
sorted(bromas.items())


Out[54]:
[('m', 7), ('n', 5), ('z', 10)]

In [57]:
def pega_segundo(sequencia):
    return sequencia[1]

sorted(bromas.items(), key=pega_segundo)


Out[57]:
[('n', 5), ('m', 7), ('z', 10)]

Neste exemplo definimos a funçao pega_segundo e enviamos ela como argumento para a função sorted()

Valores padrões de argumentos (default arguments)

O Python permite a atribuição de valores padrão para argumentos de uma função. Ao chamar essa função esses argumentos são opcionais, sendo utilizado o valor padrão fornecido na definição da função.

Por exemplo vamos criar uma função que converte um valor em dólar para real com o preço do dólar como argumento com valor padrão:


In [9]:
def dolar_para_real(valor_real, dolar=3.53):
    return valor_real * dolar

Para calular um preço de um produto de, por exemplo, U$89,00 só precisamos passar esse valor:


In [12]:
dolar_para_real(89)


Out[12]:
314.16999999999996

Supondo que queiramos calcular o preço do produto no ano passado quando o valor do dólar estava menor:


In [13]:
dolar_para_real(89, 2.8)


Out[13]:
249.2

Muitas funções da biblioteca padrão usam argumentos padrão para simplificar e extender seus usos. Muita funções que vimos neste curso fazem isso, como, por exemplo a função str.split().

Para mostrar isso vamos recorrer a sua documentação que é invocada ao passar essa função como argumento para a função help():


In [15]:
help(str.split)


Help on method_descriptor:

split(...)
    S.split(sep=None, maxsplit=-1) -> list of strings
    
    Return a list of the words in S, using sep as the
    delimiter string.  If maxsplit is given, at most maxsplit
    splits are done. If sep is not specified or is None, any
    whitespace string is a separator and empty strings are
    removed from the result.

Como visto a função split possui dois argumentos com valores padrão: separador e número máximo de splits. Por padrão o separador é um espaço em branco e o número máximo de splits é todos os possíveis, como podemos observar neste exemplo:


In [16]:
'Frase sem sentido algum para ser usada como exemplo'.split()


Out[16]:
['Frase', 'sem', 'sentido', 'algum', 'para', 'ser', 'usada', 'como', 'exemplo']

Podemos mudar esse comportamento passando outros argumentos:


In [21]:
frase = 'Frase sem sentido algum para ser usada como exemplo'
frase.split(' ', 1)  # somente 1 split foi feito gerando uma lista de dois elementos


Out[21]:
['Frase', 'sem sentido algum para ser usada como exemplo']

In [22]:
url = 'www.dominio.com.br'
url.split('.')


Out[22]:
['www', 'dominio', 'com', 'br']

In [24]:
url.split('.', 1)  # para separar somente o www do resto


Out[24]:
['www', 'dominio.com.br']

Outra função que também faz isso é a função open() usada para abrir arquivos:


In [32]:
arq = open('arq.txt', 'w')  # passa nome do arquivo e modo abertura 'w' (escrita)
arq  # arquivo aberto


Out[32]:
<_io.TextIOWrapper name='arq.txt' mode='w' encoding='UTF-8'>

In [33]:
arq.close()  # fechando arquivo

In [34]:
arq = open('arq.txt')  # por padrão o modo de abertura é 'r' (leitura)
arq


Out[34]:
<_io.TextIOWrapper name='arq.txt' mode='r' encoding='UTF-8'>

In [35]:
arq.close()

Veremos mais sobre esta função ainda nesta aula.

Cuidado com argumentos padrões!

Os argumentos padrões de funções são executados apenas uma vez e isso pode causar alguns comportamentos "estranhos".

Suponhamos que queremos criar uma função anexa() que adiciona um elemento a uma lista e, se a lista não for passada, criamos uma nova:


In [36]:
def anexa(elemento, lista=[]):
    lista.append(elemento)
    return lista

In [37]:
anexa(1)


Out[37]:
[1]

In [38]:
anexa(2)


Out[38]:
[1, 2]

In [39]:
anexa(3)


Out[39]:
[1, 2, 3]

Como dito anteriormente o valor do argumento da lista [] (que cria uma lista) é executado apenas uma vez, portanto a mesma lista é usada sempre que chamamos a função anexa(). Para criarmos uma anova lista quando não nos é passado uma fazemos:


In [41]:
def anexa(elemento, lista=None):
    if not lista:
        lista = []
    lista.append(elemento)
    return lista

Desse jeito criamos uma nova lista cada vez que a função é executada:


In [44]:
lista = anexa(10)
lista


Out[44]:
[10]

In [45]:
anexa(5)


Out[45]:
[5]

In [46]:
anexa(20, lista)
lista


Out[46]:
[10, 20]

Como já vimos anteriormente (porém não foi explicado como) o Python permite que os argumentos da função sejam chamados por seu nome e não somente por sua posição:


In [42]:
anexa(elemento=100, lista=[1, 2, 3])


Out[42]:
[1, 2, 3, 100]

In [47]:
'Exemplo de split chamado pelo nome dos argumentos'.split(sep=' ', maxsplit=-1)


Out[47]:
['Exemplo', 'de', 'split', 'chamado', 'pelo', 'nome', 'dos', 'argumentos']

Exemplo de uso de argumentos nomeados: biblioteca datetime

Uma função da biblioteca padrão do Python que faz uso extensivo de argumentos padrões é a timedelta() da biblioteca datetime (que trabalha com datas e horários). Essa função é usada para representar durações, diferenças entre datas ou horários:


In [4]:
from datetime import date, timedelta
hoje = date.today()
hoje  # objeto do tipo date


Out[4]:
datetime.date(2016, 5, 15)

In [78]:
hoje.year, hoje.month, hoje.day  # atributos de date: day, month e year


Out[78]:
(2016, 5, 14)

foo


In [69]:
hoje + timedelta(days=1)  # amanhã


Out[69]:
datetime.date(2016, 5, 15)

In [72]:
hoje - timedelta(days=1) # ontem


Out[72]:
datetime.date(2016, 5, 13)

In [70]:
hoje + timedelta(days=2)  # depois de amanhã


Out[70]:
datetime.date(2016, 5, 16)

In [73]:
hoje - timedelta(days=2)  # antes de ontem


Out[73]:
datetime.date(2016, 5, 12)

In [71]:
hoje + timedelta(days=7)  # semana que vem


Out[71]:
datetime.date(2016, 5, 21)

In [86]:
hoje


Out[86]:
datetime.date(2016, 5, 14)

In [82]:
hoje + timedelta(days=30)  # mês que vem


Out[82]:
datetime.date(2016, 6, 13)

Como nem todo mês possui 30 dias pode ser necessário saber qual o próximo mês. Para isso é melhor usar a função datetime.replace() que retorna a mesma data com os valores fornecidos trocados:


In [89]:
hoje.replace(month=hoje.month + 1)  # mesmo dia e ano no próximo mês


Out[89]:
datetime.date(2016, 6, 14)

In [90]:
hoje.replace(year=hoje.year + 1)  # mesmo dia e mês no próximo ano


Out[90]:
datetime.date(2017, 5, 14)

timedelta() também pode ser usado com datetimes (data e hora):


In [3]:
from datetime import datetime

agora = datetime.now()
agora


Out[3]:
datetime.datetime(2016, 5, 15, 22, 43, 4, 570704)

In [77]:
agora.year, agora.month, agora.day, agora.hour, agora.minute, agora.second, agora.microsecond


Out[77]:
(2016, 5, 14, 22, 52, 22, 176642)

In [79]:
agora + timedelta(hours=1)  # daqui uma hora


Out[79]:
datetime.datetime(2016, 5, 14, 23, 52, 22, 176642)

In [80]:
agora - timedelta(hours=1)  # uma hora atrás


Out[80]:
datetime.datetime(2016, 5, 14, 21, 52, 22, 176642)

In [81]:
agora + timedelta(hours=2, minutes=30)  # daqui 2 horas e meia


Out[81]:
datetime.datetime(2016, 5, 15, 1, 22, 22, 176642)

Subtrair dates e datetimes gera objetos timedelta que representam a diferença de tempo entre os dois:


In [11]:
daqui_a_pouco = agora + timedelta(minutes=15, seconds=45)
daqui_a_pouco - agora


Out[11]:
datetime.timedelta(0, 945)

In [9]:



Out[9]:
datetime.timedelta(1)

Chamar funções dando nomes aos seus argumentos, em conjunto com bons nomes de funções e argumentos, é uma ótima forma de aumentar a legibilidade de seu código.

Exercícios

-


In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]:

Empacotamento e desempacotamento de argumentos de funções

A criação de funções com argumentos arbitrários é feita usando o conceito de empacotamento de argumentos. Algumas funções da biblioteca padrão do Python usam esse conceito:


In [1]:
max(1, 2)  # funciona com 2 argumentos


Out[1]:
2

In [14]:
max(1, 2, 3)  # 3 argumentos


Out[14]:
3

In [17]:
max(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)  # muitos argumentos


Out[17]:
18

O que acontece é que esses vários argumentos são empacotados para uma tupla e então a partir dessa tupla de elementos é possível encontrar o máximo. A funcão sum() que soma os elementos de uma sequência não suporta argumentos abritrários, vamos fazer uma versão dessa função que suporte isso:


In [19]:
sum(1, 2, 3, 4)  # não suporta


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-19-1f367796fa58> in <module>()
----> 1 sum(1, 2, 3, 4)  # não suporta

TypeError: sum expected at most 2 arguments, got 4

O empacotamento de argumentos é feito na definição dos argumentos da função usando o operador *, conforme é mostrado a seguir. Vamos começar analisando o resultado desse argumento para depois implementar a funcionalidade de soma:


In [37]:
def soma(*numeros):
    print('O tipo é: {}'.format(type(numeros)))
    print('Valores: {}'.format(numeros))

Só para não haver dúvidas: *numeros não é um ponteiro. O que realmente acontece é que os valores recebidos ao invocar a função soma() serão empacotados para o argumento numeros.


In [31]:
soma(-1, 0, 1)


O tipo é: <class 'tuple'>
Valores: (-1, 0, 1)

Nesse exemplo a função soma() foi chamada com os valores -1, 0, 1 que foram empacotados na tupla numeros. Sabendo disso podemos calcular a soma desses elementos:


In [32]:
def soma(*numeros):
    soma = 0
    for num in numeros:
        soma += num
    return soma

In [33]:
soma(1, 2, 3, 4)


Out[33]:
10

In [35]:
soma(-2, 0, 3)


Out[35]:
1

É possível criar função que receba alguns argumentos fixos e argumentos arbitrários:


In [41]:
def foo(bar, *baz):
    print(type(bar), type(baz))
    print('bar: {}, baz: {}'.format(bar, baz))

In [42]:
foo(1, 2, 3, 4, 5)


<class 'int'> <class 'tuple'>
bar: 1, baz: (2, 3, 4, 5)

In [43]:
foo([1, 2, 3], 10, 'aba', False, (1, 2, 3))


<class 'list'> <class 'tuple'>
bar: [1, 2, 3], baz: (10, 'aba', False, (1, 2, 3))

Do mesmo jeito que empacotamos argumentos recebidos na chamada de uma função podemos desempacotar argumentos para enviar as funções:


In [47]:
numeros = -1, 0, 10
max(*numeros)


Out[47]:
10

No exemplo anterior desempacotamos a tupla com os valores -1, 0, 10 e, ao invés de enviar uma tupla, mandamos cada um deles como um argumento separado. Para deixar esse conceito claro criaremos uma função que recebe argumentos desempacotados:


In [48]:
def soma(a, b, c):
    """ Soma três números a, b, e c (a + b + c) """
    return a + b + c

Normalmente faríamos:


In [50]:
soma(1, 2, 3)


Out[50]:
6

Porém podemos desempacotar uma sequência de 3 elementos e enviá-los para a função:


In [51]:
números = -1, 0, 1
soma(*números)


Out[51]:
0

Se a lista for maior ou menor uma exceção será levantada:


In [53]:
números = -1, 0
soma(*números)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-53-984254beacd1> in <module>()
      1 números = -1, 0
----> 2 soma(*números)

TypeError: soma() missing 1 required positional argument: 'c'

In [54]:
números = -1, 0, 1, 10
soma(*números)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-54-887513f33334> in <module>()
      1 números = -1, 0, 1, 10
----> 2 soma(*números)

TypeError: soma() takes 3 positional arguments but 4 were given

Para ficar mais claro ainda vamos criar uma função que deve receber, obrigatoriamente, três argumentos fixos e, opcionalmente, quantos mais valores forem enviados:


In [63]:
def foo(a, b, c, *args):
    print('a: {} {}'.format(a, type(a)))
    print('b: {} {}'.format(b, type(b)))
    print('c: {} {}'.format(c, type(c)))
    print('*args: {} {}'.format(args, type(args)))

In [64]:
args = ['foobarbaz', False, 10]
foo(*args)


a: foobarbaz <class 'str'>
b: False <class 'bool'>
c: 10 <class 'int'>
*args: () <class 'tuple'>

Ao receber argumentos empacotados, como feito na função foo(a, b, c, *args), permitimos o envio de uma quantidade arbitrária de argumentos. Isso inclui o envio de nenhum argumento, por esse motivos as funções embutidas min() e max() definem dois argumentos fixos e depois recebem mais argumentos empacotados:


In [69]:
min(10)  # levanta exceção


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-69-5e0a09376ba4> in <module>()
----> 1 min(10)  # levanta exceção

TypeError: 'int' object is not iterable

In [72]:
min(10, -10)  # correto


Out[72]:
-10

In [73]:
min(10, -10, 0)  # também correto


Out[73]:
-10

O mesmo vale para nossa função foo():


In [74]:
foo(1)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-74-9e45007b2b59> in <module>()
----> 1 foo(1)

TypeError: foo() missing 2 required positional arguments: 'b' and 'c'

In [75]:
foo(1, 2)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-75-d63fb28d788b> in <module>()
----> 1 foo(1, 2)

TypeError: foo() missing 1 required positional argument: 'c'

In [76]:
foo(1, 2, 3)


a: 1 <class 'int'>
b: 2 <class 'int'>
c: 3 <class 'int'>
*args: () <class 'tuple'>

In [77]:
foo(1, 2, 3, 4, 5, 6, 7, 8, 9)


a: 1 <class 'int'>
b: 2 <class 'int'>
c: 3 <class 'int'>
*args: (4, 5, 6, 7, 8, 9) <class 'tuple'>

Empacotamento e desempacotamento de argumentos são conceitos importantes, uma vez que são usados extensivamente em bibliotecas e frameworks Python. Funções embutidas como format(), max() e min() usam. Além disso, muitos métodos das Class-Based Views no framework web Django também usam.

Além de empacotar e desempacotar argumentos em/de sequências também é possível fazer isso para dicionários:


In [60]:
def foo(a, b, c):
    print('a: {} {}'.format(a, type(a)))
    print('b: {} {}'.format(b, type(b)))
    print('c: {} {}'.format(c, type(c)))

In [81]:
kwargs = {'a': 1.5, 'b': True, 'c': 'alo'}
foo(**kwargs)  # desempacotando dicionário kwargs para função foo()


a: 1.5 <class 'float'>
b: True <class 'bool'>
c: alo <class 'str'>
*args: () <class 'tuple'>

O que acontece por trás disso é: os argumentos com o nome das chaves do dicionário recebem o respectivo valor, portanto é necessário se atentar com as chaves e nomes do argumentos:


In [82]:
kwargs = {'q': 10, 'x': 'foo', 'a': 123}
foo(**kwargs)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-82-61cb599c61d0> in <module>()
      1 kwargs = {'q': 10, 'x': 'foo', 'a': 123}
----> 2 foo(**kwargs)

TypeError: foo() got an unexpected keyword argument 'q'

Assim como visto anteriormente também é possível, ao criar uma função, empacotar os argumentos em dicionários:


In [83]:
def foo(a, b, c, **kwargs):  # kwargs = KeyWord Arguments (argumentos de palavra-chave)
    print('a: {} {}'.format(a, type(a)))
    print('b: {} {}'.format(b, type(b)))
    print('c: {} {}'.format(c, type(c)))
    print('kwargs: {} {}'.format(kwargs, type(kwargs)))

In [84]:
foo(1, 2, 3)


a: 1 <class 'int'>
b: 2 <class 'int'>
c: 3 <class 'int'>
kwargs: {} <class 'dict'>

In [85]:
foo(1, 2, 3, nome='José', idade=100, vivo=True)


a: 1 <class 'int'>
b: 2 <class 'int'>
c: 3 <class 'int'>
kwargs: {'vivo': True, 'idade': 100, 'nome': 'José'} <class 'dict'>

A função str.format() recebe argumentos posicionais e de palavra-chave arbitrários que devem corresponder a quantidade de variáveis a ser substituidas na string de formatação:


In [86]:
'{0}'.format(1)


Out[86]:
'1'

In [87]:
'{0} {1}'.format(1, 2)


Out[87]:
'1 2'

Podemos desempacotar uma sequência e enviar à função de formatação:


In [88]:
numeros = [1, 2, 3, 4, 5]
'{0} {1} {2} {3} {4}'.format(*numeros)


Out[88]:
'1 2 3 4 5'

In [90]:
'{nome} é {sexo} e tem {idade} anos de idade.'.format(nome='Joana', sexo='mulher', idade=35)


Out[90]:
'Joana é mulher e tem 35 anos de idade.'

Podemos desempacotar um dicionários e enviar essas informações à função:


In [92]:
dados = {'nome': 'Joana', 'sexo': 'mulher', 'idade': 35}
'{nome} é {sexo} e tem {idade} anos de idade.'.format(**dados)


Out[92]:
'Joana é mulher e tem 35 anos de idade.'

Para criar uma função que receba argumentos arbitrários é preciso criar uma função que empacote tanto os argumentos posicionais (em uma tupla) quanto os nomeados (em um dicionários):


In [94]:
def silverbullet(*args, **kwargs):
    print('args: {} {}'.format(args, type(args)))
    print('kwargs: {} {}'.format(kwargs, type(kwargs)))

In [95]:
silverbullet(1, 2, 3, 4, a=10, b=20, c=30)


args: (1, 2, 3, 4) <class 'tuple'>
kwargs: {'a': 10, 'b': 20, 'c': 30} <class 'dict'>

In [97]:
foo = 1, 2, 3
bar = {'abc': False, 'def': 'alololo'}
silverbullet(-1, -10, *foo, a=150, b='oi', **bar)


args: (-1, -10, 1, 2, 3) <class 'tuple'>
kwargs: {'abc': False, 'b': 'oi', 'def': 'alololo', 'a': 150} <class 'dict'>

Arquivos

Já vimos anteriormente um exemplo do uso de arquivos, aqui nesta seção vamos trabalhar mais a fundo com eles.

Para abrir um arquivo existe a função embutida open() que recebe, além de outras coisas, o nome do arquivo e modo de abertura. Os modos suportados são:

Character Meaning
'r'abrir par leitura (padrão)
'w'abrir para escrita, o arquivo é truncado primeiro
'x'abrir para criação exclusiva, falhando se o arquivo existe
'a'abrir para escrita, anexando o conteúdo para o fim do arquivo caso ele exista
'b'modo binário (pode ser usado em conjunto com os de abertura)
't'modo texto (padrão)
'+'abrir um arquivo do disco para atualização (funciona para escrita e leitura)
'U'modo quebra de linhas universal (depreciado)

Vamos começar abrindo um arquivo de texto para escrita:


In [18]:
arq = open('dados.txt', 'w')
arq


Out[18]:
<_io.TextIOWrapper name='dados.txt' mode='w' encoding='UTF-8'>

In [19]:
arq.write('você tem dado em casa?\n')
arq.write('não teve graça... eu sei.')
arq.close()

Agora abra o arquivo dados.txt e veja seu conteúdo.

Note que após fechar o arquivo não podemos fazer operações nele:


In [20]:
arq.write('esqueci de escrever esta frase')


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-7ccb0db4a2ec> in <module>()
----> 1 arq.write('esqueci de escrever esta frase')

ValueError: I/O operation on closed file.

Agora vamos usar o próprio python para ler o arquivo:


In [21]:
arq = open('dados.txt')

In [26]:
conteudo = arq.read()
conteudo


Out[26]:
'você tem dado em casa?\nnão teve graça... eu sei.'

Como visto a função file.read() nos dá o conteúdo de todo o arquivo como uma única string. Mais para frente veremos outros métodos de leitura e escrita.


In [28]:
arq.close()  # não podemos esquecer de fechar o arquivo

Agora vamos gerar um arquivo mais complexo com dados mais úteis usando a famigerada biblioteca faker:


In [35]:
from faker import Factory
faker = Factory.create('pt_BR')  # cria fábrica de dados falsos em pt-BR

arq = open('dados.txt', 'w')
for _ in range(100):
    nome = faker.name()
    cargo = faker.job()
    empresa = faker.company()
    arq.write('"{}","{}","{}"\n'.format(nome, cargo, empresa))
    
    
arq.close()

Abra o arquivo dados.txt e dentro dele haverá 100 linhas. Cada linha contém os dados (nome, cargo e empresa) separados por vírgula.

Esse formato de dados é muito popular e é chamado de CSV (Comma-separated Values ou Valores Separados por Vírgula), muitas empresas usam o CSV para mover dados entre sistemas que trabalham com formatos incompatíveis ou proprietários. Ainda nesta aula veremos mais sobre como trabalhar com esses dados.

Existem algumas maneiras diferentes para ler arquivo. Podemos ler todas as linhas de uma só vez e jogá-la em uma lista (ou iterá-la diretamente) usando file.readlines():


In [36]:
arq = open('dados.txt')  # abrimos o arquivo no modo padrão (escrita)
linhas = arq.readlines()  # o arquivo é todo lido e cada linha vira um elmento na lista linhas
print(type(linhas))
print(linhas)
arq.close()


<class 'list'>
['"Dr. Felipe Costela","Tourism officer","Silva"\n', '"Srta. Bruna Ferreira","Advertising account executive","Ferreira - EI"\n', '"Heitor Dias","Surveyor, insurance","Araújo"\n', '"Alexia Pinto","Psychotherapist","Barros e Filhos"\n', '"Lara Rocha","Psychologist, occupational","Azevedo Silva S/A"\n', '"Isabelly Araújo","Lexicographer","Silva"\n', '"Dra. Sabrina Santos","Best boy","Cunha Almeida Ltda."\n', '"Nathan Fernandes","Archivist","Araújo Rodrigues - EI"\n', '"Thiago Lima","Chiropodist","Araújo"\n', '"Nathan Silva","Web designer","Ferreira"\n', '"João Barros","Engineer, electrical","Pereira - ME"\n', '"Sra. Amanda Oliveira","Ophthalmologist","Silva Cardoso - EI"\n', '"Dr. Carlos Eduardo Correia","Therapist, music","Souza"\n', '"Sr. Daniel Ribeiro","Financial trader","Barros"\n', '"Srta. Fernanda Araújo","Teacher, primary school","Fernandes"\n', '"Gabriel Correia","Naval architect","Santos Cunha - ME"\n', '"João Vitor Fernandes","Engineer, drilling","Barros"\n', '"Anthony Rodrigues","Insurance broker","Pereira"\n', '"Lara Carvalho","Financial planner","Cunha S.A."\n', '"Bryan Azevedo","Quantity surveyor","Pinto"\n', '"Maysa Dias","Surveyor, building","Barros Ferreira Ltda."\n', '"Srta. Isadora Silva","Medical physicist","Pinto Pereira - ME"\n', '"Marina Barbosa","Lexicographer","Silva"\n', '"Bryan Castro","Designer, exhibition/display","Correia - EI"\n', '"Maysa Castro","Network engineer","Souza - ME"\n', '"Augusto Carvalho","Agricultural engineer","Rocha - ME"\n', '"Nicole Alves","Engineer, materials","Dias S.A."\n', '"Ana Vitória Pereira","Television floor manager","Melo Lima S/A"\n', '"Murilo Souza","Radio producer","Cunha Rocha - EI"\n', '"Ana Vitória Dias","Housing manager/officer","Gomes S.A."\n', '"Nicole Ferreira","Architect","Alves"\n', '"Ana Rocha","Maintenance engineer","Alves"\n', '"Rafael Barros","Production designer, theatre/television/film","Costela Castro e Filhos"\n', '"Kamilly Carvalho","Pharmacologist","Barros"\n', '"Gabriel Barros","Lawyer","Souza"\n', '"Pedro Henrique Santos","Warden/ranger","Melo S.A."\n', '"Nina Cunha","Medical technical officer","Barros"\n', '"Benício Carvalho","Local government officer","Correia"\n', '"Murilo Lima","Building services engineer","Ferreira - ME"\n', '"Maria Cecília Rodrigues","Oceanographer","Gomes Carvalho Ltda."\n', '"Elisa Ferreira","Administrator, Civil Service","Cunha Azevedo Ltda."\n', '"Luana Souza","Scientist, research (life sciences)","Melo Silva - ME"\n', '"João Guilherme Ribeiro","Technical sales engineer","Gomes"\n', '"Alana Correia","Mechanical engineer","Ribeiro - EI"\n', '"Gabriela Cunha","Sales executive","Rodrigues Ltda."\n', '"Joana Azevedo","Contracting civil engineer","Costela e Filhos"\n', '"Maria Julia Santos","Marine scientist","Correia"\n', '"Dra. Mariana Barbosa","Midwife","Araújo - EI"\n', '"Cauê Silva","Structural engineer","Ferreira"\n', '"Rafaela Ribeiro","Petroleum engineer","Oliveira"\n', '"Giovanna Pinto","Lighting technician, broadcasting/film/video","Melo"\n', '"Francisco Santos","Archivist","Pinto"\n', '"Joana Cardoso","Equities trader","Dias"\n', '"Vitor Gabriel Correia","Communications engineer","Martins"\n', '"João Dias","Physiotherapist","Carvalho"\n', '"Dr. Matheus Fernandes","Nature conservation officer","Pereira e Filhos"\n', '"Dra. Eduarda Costela","Government social research officer","Alves e Filhos"\n', '"Paulo Gomes","Financial manager","Ribeiro"\n', '"Lívia Azevedo","Education administrator","Araújo"\n', '"Vinicius Dias","Careers adviser","Barbosa - ME"\n', '"Augusto Barbosa","Engineer, building services","Pereira"\n', '"Bárbara Melo","Buyer, retail","Rocha"\n', '"Pietro Barros","Social worker","Gomes Melo S/A"\n', '"Eloah Castro","Restaurant manager, fast food","Pinto"\n', '"Ana Ferreira","Forensic scientist","Rodrigues S/A"\n', '"Arthur Ribeiro","Sales professional, IT","Ribeiro - ME"\n', '"Rebeca Ribeiro","Biomedical scientist","Cardoso"\n', '"Heloísa Carvalho","Designer, furniture","Dias"\n', '"Isabelly Rodrigues","Theatre director","Rodrigues S.A."\n', '"Ryan Castro","Advertising account executive","Pinto Alves S.A."\n', '"Lucca Pereira","Administrator","Alves"\n', '"Alice Rocha","Sales professional, IT","Carvalho"\n', '"Isaac Martins","Ceramics designer","Barbosa"\n', '"Clarice Azevedo","Insurance underwriter","Dias - EI"\n', '"Rodrigo Pereira","Buyer, industrial","Almeida - ME"\n', '"Bernardo Melo","Restaurant manager, fast food","Almeida e Filhos"\n', '"Rodrigo Castro","Research scientist (life sciences)","Lima"\n', '"Dr. Raul Correia","Psychologist, prison and probation services","Araújo Barbosa - ME"\n', '"Sr. Calebe Melo","Learning disability nurse","Lima"\n', '"Breno Costela","Engineer, materials","Melo"\n', '"Ian Barros","Brewing technologist","Oliveira Ltda."\n', '"Yuri Melo","Make","Souza Rodrigues Ltda."\n', '"Yuri Ferreira","Media planner","Melo S.A."\n', '"Pietro Silva","IT sales professional","Cardoso"\n', '"Brenda Alves","Illustrator","Correia Carvalho S/A"\n', '"Renan Barbosa","Acupuncturist","Cunha"\n', '"Pedro Silva","Environmental consultant","Castro"\n', '"Maria Julia Almeida","Librarian, public","Araújo Pinto Ltda."\n', '"Erick Barros","Engineer, electrical","Barros Barbosa S/A"\n', '"Otávio Silva","Administrator, Civil Service","Pinto"\n', '"Ana Carolina Alves","Haematologist","Costela"\n', '"Giovanna Correia","Product designer","Alves S/A"\n', '"Maysa Oliveira","Magazine features editor","Melo - ME"\n', '"Enzo Gabriel Souza","Fish farm manager","Dias"\n', '"Sr. Vitor Gabriel Barbosa","Structural engineer","Dias"\n', '"Olivia Ferreira","Production manager","Melo Correia e Filhos"\n', '"Sra. Maria Alice Rodrigues","Television floor manager","Oliveira Souza S.A."\n', '"Theo Pereira","Scientist, audiological","Azevedo e Filhos"\n', '"Valentina Azevedo","Field seismologist","Souza"\n', '"Joaquim Almeida","Psychologist, educational","Gomes Almeida e Filhos"\n']

Podemos iterar a lista e trabalhar com os dados vindo do arquivo:


In [37]:
for linha in linhas[:10]:  # pegando só as 10 primeiras por brevidade
    print(linha.strip())  # .strip() remove a quebra de linha no final


"Dr. Felipe Costela","Tourism officer","Silva"
"Srta. Bruna Ferreira","Advertising account executive","Ferreira - EI"
"Heitor Dias","Surveyor, insurance","Araújo"
"Alexia Pinto","Psychotherapist","Barros e Filhos"
"Lara Rocha","Psychologist, occupational","Azevedo Silva S/A"
"Isabelly Araújo","Lexicographer","Silva"
"Dra. Sabrina Santos","Best boy","Cunha Almeida Ltda."
"Nathan Fernandes","Archivist","Araújo Rodrigues - EI"
"Thiago Lima","Chiropodist","Araújo"
"Nathan Silva","Web designer","Ferreira"

Como vocês viram anteriormente abrimos o arquivo, mexemos com ele e depois o fechamos. Trabalhar dessa forma geralmente pode levar a erros, pois é comum esquecer de fechar o arquivo e, ter vários arquivos abertos, pode deixar o programa lento/ineficiente. (eu mesmo esqueci de fechar os arquivos nos dois exemplos acima)

Uma maneira melhor de manipular arquivos é usando gerenciadores de contexto se responsabilizam pelo fechamento ou finalização de recursos utilizados e isso pode ser usado para trabalhar com arquivos ou cuidar de transações ao trabalhar com banco de dados, por exemplo.

Vamos mostrar como trabalhar com gerenciadores de contexto lendo o arquivo que criamos anteriormente:


In [38]:
with open('dados.txt') as arq:  # abre o arquivo numeros.txt e o coloca na variável arq
    for linha in arq.readlines()[-10:]:  # pega as 10 últimas linhas por brevidade
        print(linha.strip())


"Ana Carolina Alves","Haematologist","Costela"
"Giovanna Correia","Product designer","Alves S/A"
"Maysa Oliveira","Magazine features editor","Melo - ME"
"Enzo Gabriel Souza","Fish farm manager","Dias"
"Sr. Vitor Gabriel Barbosa","Structural engineer","Dias"
"Olivia Ferreira","Production manager","Melo Correia e Filhos"
"Sra. Maria Alice Rodrigues","Television floor manager","Oliveira Souza S.A."
"Theo Pereira","Scientist, audiological","Azevedo e Filhos"
"Valentina Azevedo","Field seismologist","Souza"
"Joaquim Almeida","Psychologist, educational","Gomes Almeida e Filhos"

O arquivo arq já foi fechado, podemos verificar isso tentando ler uma linha do arquivo:


In [33]:
arq.readline()


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-33-57520091610e> in <module>()
----> 1 arq.readline()

ValueError: I/O operation on closed file.

Tambem é possível ler o arquivo linha a linha usando a função file.readline():


In [39]:
with open('dados.txt') as arq:
    linha = arq.readline()
    while linha:
        print(linha, end='')
        linha = arq.readline()


"Dr. Felipe Costela","Tourism officer","Silva"
"Srta. Bruna Ferreira","Advertising account executive","Ferreira - EI"
"Heitor Dias","Surveyor, insurance","Araújo"
"Alexia Pinto","Psychotherapist","Barros e Filhos"
"Lara Rocha","Psychologist, occupational","Azevedo Silva S/A"
"Isabelly Araújo","Lexicographer","Silva"
"Dra. Sabrina Santos","Best boy","Cunha Almeida Ltda."
"Nathan Fernandes","Archivist","Araújo Rodrigues - EI"
"Thiago Lima","Chiropodist","Araújo"
"Nathan Silva","Web designer","Ferreira"
"João Barros","Engineer, electrical","Pereira - ME"
"Sra. Amanda Oliveira","Ophthalmologist","Silva Cardoso - EI"
"Dr. Carlos Eduardo Correia","Therapist, music","Souza"
"Sr. Daniel Ribeiro","Financial trader","Barros"
"Srta. Fernanda Araújo","Teacher, primary school","Fernandes"
"Gabriel Correia","Naval architect","Santos Cunha - ME"
"João Vitor Fernandes","Engineer, drilling","Barros"
"Anthony Rodrigues","Insurance broker","Pereira"
"Lara Carvalho","Financial planner","Cunha S.A."
"Bryan Azevedo","Quantity surveyor","Pinto"
"Maysa Dias","Surveyor, building","Barros Ferreira Ltda."
"Srta. Isadora Silva","Medical physicist","Pinto Pereira - ME"
"Marina Barbosa","Lexicographer","Silva"
"Bryan Castro","Designer, exhibition/display","Correia - EI"
"Maysa Castro","Network engineer","Souza - ME"
"Augusto Carvalho","Agricultural engineer","Rocha - ME"
"Nicole Alves","Engineer, materials","Dias S.A."
"Ana Vitória Pereira","Television floor manager","Melo Lima S/A"
"Murilo Souza","Radio producer","Cunha Rocha - EI"
"Ana Vitória Dias","Housing manager/officer","Gomes S.A."
"Nicole Ferreira","Architect","Alves"
"Ana Rocha","Maintenance engineer","Alves"
"Rafael Barros","Production designer, theatre/television/film","Costela Castro e Filhos"
"Kamilly Carvalho","Pharmacologist","Barros"
"Gabriel Barros","Lawyer","Souza"
"Pedro Henrique Santos","Warden/ranger","Melo S.A."
"Nina Cunha","Medical technical officer","Barros"
"Benício Carvalho","Local government officer","Correia"
"Murilo Lima","Building services engineer","Ferreira - ME"
"Maria Cecília Rodrigues","Oceanographer","Gomes Carvalho Ltda."
"Elisa Ferreira","Administrator, Civil Service","Cunha Azevedo Ltda."
"Luana Souza","Scientist, research (life sciences)","Melo Silva - ME"
"João Guilherme Ribeiro","Technical sales engineer","Gomes"
"Alana Correia","Mechanical engineer","Ribeiro - EI"
"Gabriela Cunha","Sales executive","Rodrigues Ltda."
"Joana Azevedo","Contracting civil engineer","Costela e Filhos"
"Maria Julia Santos","Marine scientist","Correia"
"Dra. Mariana Barbosa","Midwife","Araújo - EI"
"Cauê Silva","Structural engineer","Ferreira"
"Rafaela Ribeiro","Petroleum engineer","Oliveira"
"Giovanna Pinto","Lighting technician, broadcasting/film/video","Melo"
"Francisco Santos","Archivist","Pinto"
"Joana Cardoso","Equities trader","Dias"
"Vitor Gabriel Correia","Communications engineer","Martins"
"João Dias","Physiotherapist","Carvalho"
"Dr. Matheus Fernandes","Nature conservation officer","Pereira e Filhos"
"Dra. Eduarda Costela","Government social research officer","Alves e Filhos"
"Paulo Gomes","Financial manager","Ribeiro"
"Lívia Azevedo","Education administrator","Araújo"
"Vinicius Dias","Careers adviser","Barbosa - ME"
"Augusto Barbosa","Engineer, building services","Pereira"
"Bárbara Melo","Buyer, retail","Rocha"
"Pietro Barros","Social worker","Gomes Melo S/A"
"Eloah Castro","Restaurant manager, fast food","Pinto"
"Ana Ferreira","Forensic scientist","Rodrigues S/A"
"Arthur Ribeiro","Sales professional, IT","Ribeiro - ME"
"Rebeca Ribeiro","Biomedical scientist","Cardoso"
"Heloísa Carvalho","Designer, furniture","Dias"
"Isabelly Rodrigues","Theatre director","Rodrigues S.A."
"Ryan Castro","Advertising account executive","Pinto Alves S.A."
"Lucca Pereira","Administrator","Alves"
"Alice Rocha","Sales professional, IT","Carvalho"
"Isaac Martins","Ceramics designer","Barbosa"
"Clarice Azevedo","Insurance underwriter","Dias - EI"
"Rodrigo Pereira","Buyer, industrial","Almeida - ME"
"Bernardo Melo","Restaurant manager, fast food","Almeida e Filhos"
"Rodrigo Castro","Research scientist (life sciences)","Lima"
"Dr. Raul Correia","Psychologist, prison and probation services","Araújo Barbosa - ME"
"Sr. Calebe Melo","Learning disability nurse","Lima"
"Breno Costela","Engineer, materials","Melo"
"Ian Barros","Brewing technologist","Oliveira Ltda."
"Yuri Melo","Make","Souza Rodrigues Ltda."
"Yuri Ferreira","Media planner","Melo S.A."
"Pietro Silva","IT sales professional","Cardoso"
"Brenda Alves","Illustrator","Correia Carvalho S/A"
"Renan Barbosa","Acupuncturist","Cunha"
"Pedro Silva","Environmental consultant","Castro"
"Maria Julia Almeida","Librarian, public","Araújo Pinto Ltda."
"Erick Barros","Engineer, electrical","Barros Barbosa S/A"
"Otávio Silva","Administrator, Civil Service","Pinto"
"Ana Carolina Alves","Haematologist","Costela"
"Giovanna Correia","Product designer","Alves S/A"
"Maysa Oliveira","Magazine features editor","Melo - ME"
"Enzo Gabriel Souza","Fish farm manager","Dias"
"Sr. Vitor Gabriel Barbosa","Structural engineer","Dias"
"Olivia Ferreira","Production manager","Melo Correia e Filhos"
"Sra. Maria Alice Rodrigues","Television floor manager","Oliveira Souza S.A."
"Theo Pereira","Scientist, audiological","Azevedo e Filhos"
"Valentina Azevedo","Field seismologist","Souza"
"Joaquim Almeida","Psychologist, educational","Gomes Almeida e Filhos"

Trabalhando com arquivos CSV

Não existe nenhum padrão de arquivos CSV. É comum ver arquivos desses formatos separados por outros caracteres que não a vírgula como: ; - e .. Em alguns casos cada coluna pode ser envolta em aspas simples ou aspas duplas. Por conta dessas particularidades o Python criou uma biblioteca csv que auxilia na manipulação de arquivos CSV.

Para ler arquivos CSV precisamos primeiro importar a biblioteca e depois criamos um leitor CSV com a função csv.reader():


In [40]:
import csv

with open("dados.txt") as arq_csv:  # abrindo o arquivo
    leitor = csv.reader(arq_csv)
    for linha in leitor:
        print(type(linha), linha)


<class 'list'> ['Dr. Felipe Costela', 'Tourism officer', 'Silva']
<class 'list'> ['Srta. Bruna Ferreira', 'Advertising account executive', 'Ferreira - EI']
<class 'list'> ['Heitor Dias', 'Surveyor, insurance', 'Araújo']
<class 'list'> ['Alexia Pinto', 'Psychotherapist', 'Barros e Filhos']
<class 'list'> ['Lara Rocha', 'Psychologist, occupational', 'Azevedo Silva S/A']
<class 'list'> ['Isabelly Araújo', 'Lexicographer', 'Silva']
<class 'list'> ['Dra. Sabrina Santos', 'Best boy', 'Cunha Almeida Ltda.']
<class 'list'> ['Nathan Fernandes', 'Archivist', 'Araújo Rodrigues - EI']
<class 'list'> ['Thiago Lima', 'Chiropodist', 'Araújo']
<class 'list'> ['Nathan Silva', 'Web designer', 'Ferreira']
<class 'list'> ['João Barros', 'Engineer, electrical', 'Pereira - ME']
<class 'list'> ['Sra. Amanda Oliveira', 'Ophthalmologist', 'Silva Cardoso - EI']
<class 'list'> ['Dr. Carlos Eduardo Correia', 'Therapist, music', 'Souza']
<class 'list'> ['Sr. Daniel Ribeiro', 'Financial trader', 'Barros']
<class 'list'> ['Srta. Fernanda Araújo', 'Teacher, primary school', 'Fernandes']
<class 'list'> ['Gabriel Correia', 'Naval architect', 'Santos Cunha - ME']
<class 'list'> ['João Vitor Fernandes', 'Engineer, drilling', 'Barros']
<class 'list'> ['Anthony Rodrigues', 'Insurance broker', 'Pereira']
<class 'list'> ['Lara Carvalho', 'Financial planner', 'Cunha S.A.']
<class 'list'> ['Bryan Azevedo', 'Quantity surveyor', 'Pinto']
<class 'list'> ['Maysa Dias', 'Surveyor, building', 'Barros Ferreira Ltda.']
<class 'list'> ['Srta. Isadora Silva', 'Medical physicist', 'Pinto Pereira - ME']
<class 'list'> ['Marina Barbosa', 'Lexicographer', 'Silva']
<class 'list'> ['Bryan Castro', 'Designer, exhibition/display', 'Correia - EI']
<class 'list'> ['Maysa Castro', 'Network engineer', 'Souza - ME']
<class 'list'> ['Augusto Carvalho', 'Agricultural engineer', 'Rocha - ME']
<class 'list'> ['Nicole Alves', 'Engineer, materials', 'Dias S.A.']
<class 'list'> ['Ana Vitória Pereira', 'Television floor manager', 'Melo Lima S/A']
<class 'list'> ['Murilo Souza', 'Radio producer', 'Cunha Rocha - EI']
<class 'list'> ['Ana Vitória Dias', 'Housing manager/officer', 'Gomes S.A.']
<class 'list'> ['Nicole Ferreira', 'Architect', 'Alves']
<class 'list'> ['Ana Rocha', 'Maintenance engineer', 'Alves']
<class 'list'> ['Rafael Barros', 'Production designer, theatre/television/film', 'Costela Castro e Filhos']
<class 'list'> ['Kamilly Carvalho', 'Pharmacologist', 'Barros']
<class 'list'> ['Gabriel Barros', 'Lawyer', 'Souza']
<class 'list'> ['Pedro Henrique Santos', 'Warden/ranger', 'Melo S.A.']
<class 'list'> ['Nina Cunha', 'Medical technical officer', 'Barros']
<class 'list'> ['Benício Carvalho', 'Local government officer', 'Correia']
<class 'list'> ['Murilo Lima', 'Building services engineer', 'Ferreira - ME']
<class 'list'> ['Maria Cecília Rodrigues', 'Oceanographer', 'Gomes Carvalho Ltda.']
<class 'list'> ['Elisa Ferreira', 'Administrator, Civil Service', 'Cunha Azevedo Ltda.']
<class 'list'> ['Luana Souza', 'Scientist, research (life sciences)', 'Melo Silva - ME']
<class 'list'> ['João Guilherme Ribeiro', 'Technical sales engineer', 'Gomes']
<class 'list'> ['Alana Correia', 'Mechanical engineer', 'Ribeiro - EI']
<class 'list'> ['Gabriela Cunha', 'Sales executive', 'Rodrigues Ltda.']
<class 'list'> ['Joana Azevedo', 'Contracting civil engineer', 'Costela e Filhos']
<class 'list'> ['Maria Julia Santos', 'Marine scientist', 'Correia']
<class 'list'> ['Dra. Mariana Barbosa', 'Midwife', 'Araújo - EI']
<class 'list'> ['Cauê Silva', 'Structural engineer', 'Ferreira']
<class 'list'> ['Rafaela Ribeiro', 'Petroleum engineer', 'Oliveira']
<class 'list'> ['Giovanna Pinto', 'Lighting technician, broadcasting/film/video', 'Melo']
<class 'list'> ['Francisco Santos', 'Archivist', 'Pinto']
<class 'list'> ['Joana Cardoso', 'Equities trader', 'Dias']
<class 'list'> ['Vitor Gabriel Correia', 'Communications engineer', 'Martins']
<class 'list'> ['João Dias', 'Physiotherapist', 'Carvalho']
<class 'list'> ['Dr. Matheus Fernandes', 'Nature conservation officer', 'Pereira e Filhos']
<class 'list'> ['Dra. Eduarda Costela', 'Government social research officer', 'Alves e Filhos']
<class 'list'> ['Paulo Gomes', 'Financial manager', 'Ribeiro']
<class 'list'> ['Lívia Azevedo', 'Education administrator', 'Araújo']
<class 'list'> ['Vinicius Dias', 'Careers adviser', 'Barbosa - ME']
<class 'list'> ['Augusto Barbosa', 'Engineer, building services', 'Pereira']
<class 'list'> ['Bárbara Melo', 'Buyer, retail', 'Rocha']
<class 'list'> ['Pietro Barros', 'Social worker', 'Gomes Melo S/A']
<class 'list'> ['Eloah Castro', 'Restaurant manager, fast food', 'Pinto']
<class 'list'> ['Ana Ferreira', 'Forensic scientist', 'Rodrigues S/A']
<class 'list'> ['Arthur Ribeiro', 'Sales professional, IT', 'Ribeiro - ME']
<class 'list'> ['Rebeca Ribeiro', 'Biomedical scientist', 'Cardoso']
<class 'list'> ['Heloísa Carvalho', 'Designer, furniture', 'Dias']
<class 'list'> ['Isabelly Rodrigues', 'Theatre director', 'Rodrigues S.A.']
<class 'list'> ['Ryan Castro', 'Advertising account executive', 'Pinto Alves S.A.']
<class 'list'> ['Lucca Pereira', 'Administrator', 'Alves']
<class 'list'> ['Alice Rocha', 'Sales professional, IT', 'Carvalho']
<class 'list'> ['Isaac Martins', 'Ceramics designer', 'Barbosa']
<class 'list'> ['Clarice Azevedo', 'Insurance underwriter', 'Dias - EI']
<class 'list'> ['Rodrigo Pereira', 'Buyer, industrial', 'Almeida - ME']
<class 'list'> ['Bernardo Melo', 'Restaurant manager, fast food', 'Almeida e Filhos']
<class 'list'> ['Rodrigo Castro', 'Research scientist (life sciences)', 'Lima']
<class 'list'> ['Dr. Raul Correia', 'Psychologist, prison and probation services', 'Araújo Barbosa - ME']
<class 'list'> ['Sr. Calebe Melo', 'Learning disability nurse', 'Lima']
<class 'list'> ['Breno Costela', 'Engineer, materials', 'Melo']
<class 'list'> ['Ian Barros', 'Brewing technologist', 'Oliveira Ltda.']
<class 'list'> ['Yuri Melo', 'Make', 'Souza Rodrigues Ltda.']
<class 'list'> ['Yuri Ferreira', 'Media planner', 'Melo S.A.']
<class 'list'> ['Pietro Silva', 'IT sales professional', 'Cardoso']
<class 'list'> ['Brenda Alves', 'Illustrator', 'Correia Carvalho S/A']
<class 'list'> ['Renan Barbosa', 'Acupuncturist', 'Cunha']
<class 'list'> ['Pedro Silva', 'Environmental consultant', 'Castro']
<class 'list'> ['Maria Julia Almeida', 'Librarian, public', 'Araújo Pinto Ltda.']
<class 'list'> ['Erick Barros', 'Engineer, electrical', 'Barros Barbosa S/A']
<class 'list'> ['Otávio Silva', 'Administrator, Civil Service', 'Pinto']
<class 'list'> ['Ana Carolina Alves', 'Haematologist', 'Costela']
<class 'list'> ['Giovanna Correia', 'Product designer', 'Alves S/A']
<class 'list'> ['Maysa Oliveira', 'Magazine features editor', 'Melo - ME']
<class 'list'> ['Enzo Gabriel Souza', 'Fish farm manager', 'Dias']
<class 'list'> ['Sr. Vitor Gabriel Barbosa', 'Structural engineer', 'Dias']
<class 'list'> ['Olivia Ferreira', 'Production manager', 'Melo Correia e Filhos']
<class 'list'> ['Sra. Maria Alice Rodrigues', 'Television floor manager', 'Oliveira Souza S.A.']
<class 'list'> ['Theo Pereira', 'Scientist, audiological', 'Azevedo e Filhos']
<class 'list'> ['Valentina Azevedo', 'Field seismologist', 'Souza']
<class 'list'> ['Joaquim Almeida', 'Psychologist, educational', 'Gomes Almeida e Filhos']

A função csv.reader() já retorna cada linha como uma lista Python com as aspas e quebra de linhas removidas.

Podemos deixar a leitura do arquivo ainda melhor usando desempacotamento de sequências:


In [41]:
with open('dados.txt') as arq_csv:
    leitor = csv.reader(arq_csv)
    for nome, cargo, empresa in leitor:
        print('{} trabalha como {} na {}'.format(nome, cargo, empresa))


Dr. Felipe Costela trabalha como Tourism officer na Silva
Srta. Bruna Ferreira trabalha como Advertising account executive na Ferreira - EI
Heitor Dias trabalha como Surveyor, insurance na Araújo
Alexia Pinto trabalha como Psychotherapist na Barros e Filhos
Lara Rocha trabalha como Psychologist, occupational na Azevedo Silva S/A
Isabelly Araújo trabalha como Lexicographer na Silva
Dra. Sabrina Santos trabalha como Best boy na Cunha Almeida Ltda.
Nathan Fernandes trabalha como Archivist na Araújo Rodrigues - EI
Thiago Lima trabalha como Chiropodist na Araújo
Nathan Silva trabalha como Web designer na Ferreira
João Barros trabalha como Engineer, electrical na Pereira - ME
Sra. Amanda Oliveira trabalha como Ophthalmologist na Silva Cardoso - EI
Dr. Carlos Eduardo Correia trabalha como Therapist, music na Souza
Sr. Daniel Ribeiro trabalha como Financial trader na Barros
Srta. Fernanda Araújo trabalha como Teacher, primary school na Fernandes
Gabriel Correia trabalha como Naval architect na Santos Cunha - ME
João Vitor Fernandes trabalha como Engineer, drilling na Barros
Anthony Rodrigues trabalha como Insurance broker na Pereira
Lara Carvalho trabalha como Financial planner na Cunha S.A.
Bryan Azevedo trabalha como Quantity surveyor na Pinto
Maysa Dias trabalha como Surveyor, building na Barros Ferreira Ltda.
Srta. Isadora Silva trabalha como Medical physicist na Pinto Pereira - ME
Marina Barbosa trabalha como Lexicographer na Silva
Bryan Castro trabalha como Designer, exhibition/display na Correia - EI
Maysa Castro trabalha como Network engineer na Souza - ME
Augusto Carvalho trabalha como Agricultural engineer na Rocha - ME
Nicole Alves trabalha como Engineer, materials na Dias S.A.
Ana Vitória Pereira trabalha como Television floor manager na Melo Lima S/A
Murilo Souza trabalha como Radio producer na Cunha Rocha - EI
Ana Vitória Dias trabalha como Housing manager/officer na Gomes S.A.
Nicole Ferreira trabalha como Architect na Alves
Ana Rocha trabalha como Maintenance engineer na Alves
Rafael Barros trabalha como Production designer, theatre/television/film na Costela Castro e Filhos
Kamilly Carvalho trabalha como Pharmacologist na Barros
Gabriel Barros trabalha como Lawyer na Souza
Pedro Henrique Santos trabalha como Warden/ranger na Melo S.A.
Nina Cunha trabalha como Medical technical officer na Barros
Benício Carvalho trabalha como Local government officer na Correia
Murilo Lima trabalha como Building services engineer na Ferreira - ME
Maria Cecília Rodrigues trabalha como Oceanographer na Gomes Carvalho Ltda.
Elisa Ferreira trabalha como Administrator, Civil Service na Cunha Azevedo Ltda.
Luana Souza trabalha como Scientist, research (life sciences) na Melo Silva - ME
João Guilherme Ribeiro trabalha como Technical sales engineer na Gomes
Alana Correia trabalha como Mechanical engineer na Ribeiro - EI
Gabriela Cunha trabalha como Sales executive na Rodrigues Ltda.
Joana Azevedo trabalha como Contracting civil engineer na Costela e Filhos
Maria Julia Santos trabalha como Marine scientist na Correia
Dra. Mariana Barbosa trabalha como Midwife na Araújo - EI
Cauê Silva trabalha como Structural engineer na Ferreira
Rafaela Ribeiro trabalha como Petroleum engineer na Oliveira
Giovanna Pinto trabalha como Lighting technician, broadcasting/film/video na Melo
Francisco Santos trabalha como Archivist na Pinto
Joana Cardoso trabalha como Equities trader na Dias
Vitor Gabriel Correia trabalha como Communications engineer na Martins
João Dias trabalha como Physiotherapist na Carvalho
Dr. Matheus Fernandes trabalha como Nature conservation officer na Pereira e Filhos
Dra. Eduarda Costela trabalha como Government social research officer na Alves e Filhos
Paulo Gomes trabalha como Financial manager na Ribeiro
Lívia Azevedo trabalha como Education administrator na Araújo
Vinicius Dias trabalha como Careers adviser na Barbosa - ME
Augusto Barbosa trabalha como Engineer, building services na Pereira
Bárbara Melo trabalha como Buyer, retail na Rocha
Pietro Barros trabalha como Social worker na Gomes Melo S/A
Eloah Castro trabalha como Restaurant manager, fast food na Pinto
Ana Ferreira trabalha como Forensic scientist na Rodrigues S/A
Arthur Ribeiro trabalha como Sales professional, IT na Ribeiro - ME
Rebeca Ribeiro trabalha como Biomedical scientist na Cardoso
Heloísa Carvalho trabalha como Designer, furniture na Dias
Isabelly Rodrigues trabalha como Theatre director na Rodrigues S.A.
Ryan Castro trabalha como Advertising account executive na Pinto Alves S.A.
Lucca Pereira trabalha como Administrator na Alves
Alice Rocha trabalha como Sales professional, IT na Carvalho
Isaac Martins trabalha como Ceramics designer na Barbosa
Clarice Azevedo trabalha como Insurance underwriter na Dias - EI
Rodrigo Pereira trabalha como Buyer, industrial na Almeida - ME
Bernardo Melo trabalha como Restaurant manager, fast food na Almeida e Filhos
Rodrigo Castro trabalha como Research scientist (life sciences) na Lima
Dr. Raul Correia trabalha como Psychologist, prison and probation services na Araújo Barbosa - ME
Sr. Calebe Melo trabalha como Learning disability nurse na Lima
Breno Costela trabalha como Engineer, materials na Melo
Ian Barros trabalha como Brewing technologist na Oliveira Ltda.
Yuri Melo trabalha como Make na Souza Rodrigues Ltda.
Yuri Ferreira trabalha como Media planner na Melo S.A.
Pietro Silva trabalha como IT sales professional na Cardoso
Brenda Alves trabalha como Illustrator na Correia Carvalho S/A
Renan Barbosa trabalha como Acupuncturist na Cunha
Pedro Silva trabalha como Environmental consultant na Castro
Maria Julia Almeida trabalha como Librarian, public na Araújo Pinto Ltda.
Erick Barros trabalha como Engineer, electrical na Barros Barbosa S/A
Otávio Silva trabalha como Administrator, Civil Service na Pinto
Ana Carolina Alves trabalha como Haematologist na Costela
Giovanna Correia trabalha como Product designer na Alves S/A
Maysa Oliveira trabalha como Magazine features editor na Melo - ME
Enzo Gabriel Souza trabalha como Fish farm manager na Dias
Sr. Vitor Gabriel Barbosa trabalha como Structural engineer na Dias
Olivia Ferreira trabalha como Production manager na Melo Correia e Filhos
Sra. Maria Alice Rodrigues trabalha como Television floor manager na Oliveira Souza S.A.
Theo Pereira trabalha como Scientist, audiological na Azevedo e Filhos
Valentina Azevedo trabalha como Field seismologist na Souza
Joaquim Almeida trabalha como Psychologist, educational na Gomes Almeida e Filhos

Agora vamos criar um arquivo CSV em um padrão diferente usando a função csv.writer(). Nossas colunas serão separadas por espaço em branco e cada coluna será separada por | ao invés de aspas:


In [44]:
with open('mais-dados.csv', 'w') as arq_csv:
    escritor = csv.writer(arq_csv, delimiter=' ', quotechar='|')
    for _ in range(20):
        dados = faker.name(), faker.job(), faker.company()
        escritor.writerow(dados)

Para ler o arquivo é só usar a mesma função csv.reader() usada anteriormente especificando o padrão:


In [46]:
with open('mais-dados.csv') as arq_csv:
    for linha in csv.reader(arq_csv, delimiter=' ', quotechar='|'):
        print(linha)


['Sophie Ribeiro', 'Hotel manager', 'Fernandes']
['Raquel Correia', 'Pharmacologist', 'Araújo']
['Maysa Cunha', 'Psychologist, counselling', 'Silva - EI']
['Srta. Nicole Silva', 'Secondary school teacher', 'Castro Pereira - EI']
['Sra. Raquel Rodrigues', 'Town planner', 'Almeida - EI']
['Gustavo Fernandes', 'Air broker', 'Correia']
['Sr. Thales Correia', 'Field seismologist', 'Gomes Almeida e Filhos']
['Leandro Castro', 'Heritage manager', 'Santos']
['Eduardo Pereira', 'Engineer, maintenance', 'Cunha Barros S/A']
['Luiza Alves', 'Software engineer', 'Pinto Ribeiro S/A']
['Luiza Rodrigues', 'Child psychotherapist', 'Fernandes']
['Juliana Ferreira', 'Government social research officer', 'Correia']
['Joaquim Melo', 'Public librarian', 'Fernandes - EI']
['Thiago Oliveira', 'Sports administrator', 'Costela - EI']
['Diogo Silva', 'Chartered management accountant', 'Oliveira Rocha - EI']
['Alice Souza', 'Trade union research officer', 'Gomes - EI']
['Natália Rocha', 'Sports development officer', 'Oliveira Carvalho S.A.']
['Maysa Castro', 'Engineer, manufacturing', 'Santos Azevedo S/A']
['Sra. Emanuelly Azevedo', 'Colour technologist', 'Santos']
['Juliana Santos', 'Print production planner', 'Silva']

Para mais informações sobre como usar a biblioteca csv consulte sua documentação oficial

Fim da Aula 05